/****************************************************
	文件：Bloom.cs
	作者：HuskyT
	邮箱：1005240602@qq.com
	日期：2020/8/13 17:59:59
	功能：
*****************************************************/

using System;
using UnityEngine;

namespace RenderingPractice
{
    public class Bloom : PostEffectsBase
    {
        [Range(0, 4), Tooltip("高斯模糊迭代次数")]
        public int Iterations = 3;
        [Range(0.2f, 3.0f), Tooltip("模糊范围")]
        public float BlurSpread = 0.6f;
        [Range(1, 8), Tooltip("缩放系数")]
        public int DownSample = 2;
        [Range(0.0f, 4.0f), Tooltip("亮度阈值")]
        public float LuminanceThreshold = 0.6f;

        public Shader BloomShader;
        private Material mBloomMat;

        public Material BloomMat
        {
            get
            {
                mBloomMat = CheckShaderAndCreateMaterial(BloomShader, mBloomMat);
                return mBloomMat;
            }
        }

        private void OnRenderImage(RenderTexture source, RenderTexture destination)
        {
            if (BloomMat != null)
            {
                BloomMat.SetFloat("_LuminanceThreshold", LuminanceThreshold);
                int rtWidth = source.width / DownSample; //降采样（提升性能、模糊效果）
                int rtHeight = source.height / DownSample;
                RenderTexture buffer0 = RenderTexture.GetTemporary(rtWidth, rtHeight, 0); //获取一个中间缓冲，存储高斯模糊Shader第一个Pass的结果
                buffer0.filterMode = FilterMode.Bilinear; //双线性滤波
                Graphics.Blit(source, buffer0, BloomMat, 0); //提取较亮区域（第一个Pass通道）

                for (int i = 1; i <= Iterations; i++)
                {
                    BloomMat.SetFloat("_BlurSize", 1.0f + i * BlurSpread);
                    RenderTexture buffer1 = RenderTexture.GetTemporary(rtWidth, rtHeight, 0);
                    //使用竖直方向上的一维高斯核进行滤波（第二个Pass）
                    Graphics.Blit(buffer0, buffer1, BloomMat, 1);
                    RenderTexture.ReleaseTemporary(buffer0);
                    buffer0 = buffer1;
                    buffer1 = RenderTexture.GetTemporary(rtWidth, rtHeight, 0);
                    //使用水平方向上的一维高斯核进行滤波（第三个Pass）
                    Graphics.Blit(buffer0, buffer1, BloomMat, 2);
                    RenderTexture.ReleaseTemporary(buffer0);
                    buffer0 = buffer1;
                }
                BloomMat.SetTexture("_Bloom", buffer0);
                Graphics.Blit(buffer0, destination, BloomMat, 3); //和原图像混合（第四个Pass）
                RenderTexture.ReleaseTemporary(buffer0); //释放中间缓冲
            }
            else
            {
                Graphics.Blit(source, destination);
            }
        }
    }
}
